﻿using KLF.Lib.Browser.DOM.View;
namespace KLF.Lib.Browser.DOM.Events
{
    /// <summary>
    /// The MouseEvent interface provides specific contextual information 
    /// associated with Mouse events.
    /// 
    /// The detail attribute inherited from UIEvent indicates the number of 
    /// times a mouse button has been pressed and released over the same 
    /// screen location during a user action. The attribute value is 1 when 
    /// the user begins this action and increments by 1 for each full sequence
    /// of pressing and releasing. If the user moves the mouse between the 
    /// mousedown and mouseup the value will be set to 0, indicating that no
    /// click is occurring.
    /// 
    /// In the case of nested elements mouse events are always targeted at the
    /// most deeply nested element. Ancestors of the targeted element may use
    /// bubbling to obtain notification of mouse events which occur within its 
    /// descendent elements.
    /// </summary>
    public interface IMouseEvent : IUIEvent
    {
        int button { get; }

        int clientX { get; }

        int clientY { get; }

        bool controlKey { get; }

        void initMouseEvent(string typeArg,
            bool canBubbleArg,
            bool cancelableArg,
            IAbstractView viewArg,
            int detailArg,
            int screenXArg,
            int screenYArg,
            int clientXArg,
            int clientYArg,
            bool ctrlKeyArg,
            bool altKeyArg,
            bool shiftKeyArg,
            bool metaKeyArg,
            int buttonArg,
            IEventTarget relatedTargetArg);

        bool metaKey { get; }

        IEventTarget relatedTarget { get; }

        int screenX { get; }

        int screenY { get; }

        bool shiftKey { get; }
    }

    /// <summary>
    /// The MouseEvent interface provides specific contextual information 
    /// associated with Mouse events.
    /// 
    /// The detail attribute inherited from UIEvent indicates the number of 
    /// times a mouse button has been pressed and released over the same 
    /// screen location during a user action. The attribute value is 1 when 
    /// the user begins this action and increments by 1 for each full sequence
    /// of pressing and releasing. If the user moves the mouse between the 
    /// mousedown and mouseup the value will be set to 0, indicating that no
    /// click is occurring.
    /// 
    /// In the case of nested elements mouse events are always targeted at the
    /// most deeply nested element. Ancestors of the targeted element may use
    /// bubbling to obtain notification of mouse events which occur within its 
    /// descendent elements.
    /// </summary>
    public class MouseEvent : UIEvent
    {
        #region Constructors

        internal MouseEvent(string _type)
            : base(_type)
        {
            type = _type;

            switch (_type.ToLowerInvariant())
            {
                case "click":
                case "mousedown":
                case "mouseup":
                case "mouseover":
                case "mouseout":
                    bubbles = cancelable = true;
                    break;

                case "mousemove":
                    bubbles = true;
                    cancelable = false;
                    break;
            }
        }

        #endregion

        #region DOM Level 2 Events Compliance

        public int button { get; internal set; }

        public int clientX { get; internal set; }

        public int clientY { get; internal set; }

        public bool controlKey { get; internal set; }

        public void initMouseEvent(string typeArg,
            bool canBubbleArg,
            bool cancelableArg,
            IAbstractView viewArg,
            int detailArg,
            int screenXArg,
            int screenYArg,
            int clientXArg,
            int clientYArg,
            bool ctrlKeyArg,
            bool altKeyArg,
            bool shiftKeyArg,
            bool metaKeyArg,
            int buttonArg,
            Node relatedTargetArg)
        {
            if (!dispatched)
            {
                base.initUIEvent(typeArg, canBubbleArg, cancelableArg, viewArg, detailArg);

            }
        }

        public bool metaKey { get; internal set; }

        public IEventTarget relatedTarget { get; internal set; }

        public int screenX { get; internal set; }

        public int screenY { get; internal set; }

        public bool shiftKey { get; internal set; }

        #endregion
    }
}
